# urls.py
"""
URL路由配置模块
实现API路由的设置和注册
"""
from urllib.request import Request
from pydantic import BaseModel
from fastapi import FastAPI, APIRouter, Request, Body
from typing import List, Dict, Any, Optional
from apps.apps import app_registry  # 导入应用注册表
from pkg.logger import get_logger
logger = get_logger()
# API路由前缀
# API_PREFIX = "/web"
API_PREFIX = ""


# full_prefix = f"{API_PREFIX}{app_info['prefix']}"
# router.include_router(app_router, prefix=full_prefix, tags=[app_name])

def setup_routes(app: FastAPI) -> None:
    """
    设置API路由
    :param app: FastAPI应用实例
    """
    # 创建主路由
    api_router = APIRouter(prefix=API_PREFIX)

    # 注册健康检查路由
    register_health_routes(api_router)

    # 自动注册所有应用路由
    auto_register_app_routes(api_router)

    # 将主路由添加到应用
    app.include_router(api_router)


def register_health_routes(router: APIRouter) -> None:
    """
    注册健康检查路由
    :param router: APIRouter实例
    """

    @router.get("/health", tags=["Health"], summary="健康检查")
    async def health_check() -> Dict[str, str]:
        """系统健康检查端点"""
        return {"status": "ok", "message": "Service is running"}

    class XRequest(BaseModel):
        x: str

    @router.post("/data", tags=["Health"], summary="传参说明")
    async def test(request: Request, y: XRequest = Body(None), n: str = None, m: str = None):
        '''
        FastAPI框架是无法实现json与form表单同时传同一值的，因此在本接口中采用以下规则进行参数处理：

        1. 如果需要同时传json和form表单，则需要定义两种不同的参数：
            - 对于json传参，使用`y`参数接收，类型为`XRequest`，通过`Body(None)`进行定义。
            - 对于form表单传参，使用`n`和`m`参数接收，类型为`str`，通过`Form(None)`进行定义。

        2. 如果同时传了json和form表单，则json的优先级高，form表单的参数会被忽略：
            - 在请求中同时包含json和form表单时，接口会优先解析json中的数据，并将其赋值给`y`参数。
            - 此时，form表单中的`n`和`m`参数将不会被解析和使用，即使它们与json中的键名相同。

        3. 请求示例：
            - JSON传参示例：
            ```json
            {
                "x": "json_x_value"
            }
            ```
            在这种情况下，`y.x`将获取到`json_x_value`，而`n`和`m`参数将为`None`。

            - Form表单传参示例：
            ```http
            n=form_n_value&m=form_m_value
            ```
            在这种情况下，`n`将获取到`form_n_value`，`m`将获取到`form_m_value`，而`y`参数将为`None`。

        注意：在实际使用中，建议根据具体业务需求选择合适的传参方式，并确保在前端请求中正确设置`Content-Type`头信息，以避免参数解析问题。

        :param request: 请求对象，用于获取请求的详细信息。
        :param y: 通过JSON传参的`XRequest`对象，包含`x`属性。
        :param n: 通过Form表单传参的`n`值。
        :param m: 通过Form表单传参的`m`值。
        '''
        print("from表单参数", n, m)
        print("json参数", y.x)

        # 在这里继续处理登录逻辑
        return {"message": "测试"}


def auto_register_app_routes(router: APIRouter) -> None:
    """
    自动注册所有应用路由
    :param router: APIRouter实例
    """
    # 确保应用已加载
    app_registry.load_all_apps()

    # 获取所有已注册应用
    apps = app_registry.apps

    # logger.info(f"开始自动注册 {len(apps)} 个应用的路由...")


    for app_name, app_info in apps.items():
        app_router = app_info['router']
        prefix = app_info['prefix']

        # 包含应用到主路由
        router.include_router(
            app_router,
            prefix=prefix,
            # 不使用tags，使用tags会导致路由重复
            # tags=[app_name]
        )

        # logger.info(f"✓ 已注册应用 '{app_name}' 路由 (前缀: {prefix})")

    # logger.info("所有应用路由注册完成")
